#ifndef SLICE_HPP
#define SLICE_HPP

#include <cstring>
#include <iostream>

#include "volume.hpp"

class Volume;

class Slice {
  public:
    Slice();
    Slice(const Vector3i &dim);
    Slice(const Vector3i &dim,unsigned char initial);
    Slice(const Vector3i &start,const Vector3i &end,Volume &volume);
    Slice(int startX,int startY,int startZ,int endX,int endY,int endZ,Volume &volume);
    Slice(const Slice &other);
    ~Slice();
    const Vector3i & getIndex() const;
    void setIndex(const Vector3i &index);
    int getFlatIndex() const;
    const Vector3i & getStart() const;
    const Vector3i & getEnd() const;
    const Vector3i & size() const;
    const Vector3i & getVolumeSize() const;
    double getDelta() const;
    const Vector3d & position() const;
    bool isOrphan() const;
    int & x();
    int & y();
    int & z();
    unsigned char & value();
    unsigned char & value(int index);
    unsigned char & value(const Vector3i &index);
    unsigned char * data() const;
    unsigned char * data(int x,int y, int z) const;
    Slice & operator=(const Slice &other);
    Slice & operator=(Volume &volume);
    void copy(const Slice &other);
    Slice slice(const Vector3i &start,const Vector3i &end);
    void setOffset(const Vector3i &offset);
    const Vector3i & getOffset() const;
    void replace(const Slice &other);
  private:
    bool orphan;
    int px,py,pz;
    mutable Vector3i index;
    Vector3i start,end,dim,volDim,offset,offsetEnd;
    Vector3d pos;
    double delta;
    mutable unsigned char *voxels;

    //private constructor only used for slicing another slice
    Slice(const Vector3i &start,const Vector3i &end,const Vector3i &volDim,double delta,
        const Vector3d &position,unsigned char *voxels,const Vector3i &offset);
    void init(const Vector3i &start,const Vector3i &end,Volume &volume);
};

#endif
